/* UTF8 Encoding */
/*-----------------------------------------------------------------------
|                            FILE DESCRIPTION                           |
-----------------------------------------------------------------------*/
/*----------------------------------------------------------------------
  - File name     : eString.hpp
  - Author        : liuzhihua (liuzhihuawy@163.com)
  - Update date   : 2023.05.31
  -	Brief         : String type for c++
  - Version       : v0.1
-----------------------------------------------------------------------*/
/*-----------------------------------------------------------------------
|                               UPDATE NOTE                             |
-----------------------------------------------------------------------*/
/**
  * Update note:
  * ------------   ---------------   ----------------------------------
  *     Date            Author                      Note
  * ------------   ---------------   ----------------------------------
  *   2023.05.31      liuzhihua                 Create file          
***/

#ifndef ESTRING_H
#define ESTRING_H


/*-----------------------------------------------------------------------
|                               INCLUDES                                |
-----------------------------------------------------------------------*/
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include "freeRTOS.h"
#include "log.h"
/*-----------------------------------------------------------------------
|                                DEFINES                                |
-----------------------------------------------------------------------*/

#define eFree   vPortFree
#define eString_LOG(str, ...) LOG_ERR("eString", str, ##__VA_ARGS__)
#define ESTRING_FORMAT_BUF_SIZE 128
static inline void* eMalloc(size_t size)
{
    void* ptr = pvPortMalloc(size);
    if (ptr == NULL)
    {
        eString_LOG("Malloc Failed\n");
    }
    return ptr;
}
typedef enum
{
    eSTRING_OK = 0,
    eSTRING_ERROR
}eStringState;

class eString
{
    private:
    
    char *pStr;
    uint16_t len;
    uint16_t MemSize;
    static char formatbuf[ESTRING_FORMAT_BUF_SIZE];

    public:
    
    static const uint16_t npos = static_cast<uint16_t>(-1);

    void * operator new(std::size_t size);
    void operator delete(void* ptr);

    eString(void);
    eString(const char *cstr);
    eString(const eString& estr);
    eString(uint16_t length, char Char);
    eString(uint16_t length);
    ~eString(void);

    eStringState assign(const char *cstr, uint16_t length);
    eStringState assign(const char *cstr);
    eStringState assign(const eString& estr);
    eStringState append(const char *cstr, uint16_t length);
    eStringState append(const char *cstr);
    eStringState append(const eString& estr);


    eStringState insert(uint16_t index, const char *cstr, uint16_t length);
    eStringState insert(uint16_t index, const char *cstr);
    eStringState insert(uint16_t index, const eString& estr);
    eStringState insert(uint16_t index, char Char);
    void erase(uint16_t index, uint16_t length);

    char at(uint16_t index);

    uint16_t mSize(void);

    // 获取字符串长度
    uint16_t length(void) const;

    // 判断字符串是否为空
    bool empty(void) const;
    // 清空字符串
    void clear(void);

    // 获取字符串内容
    const char *c_str(void) const;
    eString &operator=(const eString &other);
    eString &operator=(const char *cstr);

    eString &operator+=(const eString &estr);

    eString &operator+=(const char *cstr);

    eString &operator+=(char ch);

    // 连接字符串
    eString operator+(const char *cstr) const;
    eString operator+(const eString &other) const;
    eString operator+(char Char) const;

    char &operator[](uint16_t index);

    const char &operator[](uint16_t index) const;

    // 比较字符串是否相等
    bool operator==(const eString &other) const;
    // 比较字符串大小（字典序）
    bool operator<(const eString &other) const;
    bool operator>(const eString &other) const;

    // 查找子字符串的第一次出现的位置
    uint16_t find(const char *substr) const;

    // 查找子字符串的最后一次出现的位置
    uint16_t rfind(const eString& target) const;
    // 子字符串替换
    eStringState replace(const char *oldSubstr, const char *newSubstr);

    // 子字符串计数
    uint16_t count(const char *substr) const;

    eStringState zip(void);
    static const char* format(const char* format, ...);
};



/*-----------------------------------------------------------------------
|                               EXAMPLE                                 |
-----------------------------------------------------------------------*/
#if 0
void example(void)
{
    //create string
    eString str1("Hello");
    eString str2(str1);
    eString str3(10, 'H');
    //assign string
    str1.assign("World");
    str2.assign(str1);
    //append string
    str1.append("peace");
    str2.append(str1);
    //insert string
    str1.insert(5, ' ');
    str3.assign(" ");
    str2.insert(5, str3);
    //Erase and Clear and get length
    str2.erase(6, 5);
    str3.clear();
    //get char
    //operator =
    str1 = "my string lib";
    str3 = str1;
    //operator +=
    str1 += " is ok";
    eString str4;
    str4 = str1;
    str4 += str2;
    str4.clear();
    str4 += 'a';
    //operator +
    str2 = str3 + " is ok";
    str3 = str1 + str2;
    str4 = str1 + 'a';
    //operator []
    str4[3] = 't';
    //operator < > ==
    str2 = "string";
    //find
    str3 = "aabbccddeeffaabbccddeeffaa";
    //replace & count
    str3.replace("aa", "zz");
    str3 = "0123456789";
    str3 = "0123";
    str3.zip();
    //new delete
    eString *mstr = new eString("test");
    *mstr += str1;
    *mstr = str1 + str2;
    delete mstr;
}
#endif
#endif
